package com.example.Windturbine.Service.Impl;

import com.example.Windturbine.Controller.ViewObject.GraphVO.GraphNodeVO;
import com.example.Windturbine.Controller.ViewObject.GraphVO.GraphRelationNode;
import com.example.Windturbine.Controller.ViewObject.GraphVO.GraphVO;
import com.example.Windturbine.Dao.ProductDOMapper;
import com.example.Windturbine.Dao.ProductInfoDOMapper;
import com.example.Windturbine.DataObject.ProductDO;
import com.example.Windturbine.DataObject.ProductInfoDO;
import com.example.Windturbine.Error.BusinessException;
import com.example.Windturbine.Error.EmBusinessError;
import com.example.Windturbine.Response.CommonResult;
import com.example.Windturbine.Service.Model.ProductModel;
import com.example.Windturbine.Service.PartService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author 丁永新
 * @Date 2021/12/18
 */
@Service
public class PartServiceImpl implements PartService {



    @Resource
    ProductInfoDOMapper productInfoDOMapper;




    @Override
    public List<ProductInfoDO> getAll() throws BusinessException {
        List<ProductInfoDO> productInfoDOList = productInfoDOMapper.selectAll();
        if(productInfoDOList==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询产品信息失败！");
        }
        return productInfoDOList;
    }


    //获取用户零件信息
    @Override
    public List<ProductInfoDO> getUserPart(Integer id) throws BusinessException {
        List<ProductInfoDO> productInfoDOList = productInfoDOMapper.selectByUserId(id);
        if(productInfoDOList==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询用户的零件信息失败！");
        }
        return productInfoDOList;
    }


    //查询零件的图信息

    /**
     * 该方法暂时没用到
     * @param id
     * @return
     * @throws BusinessException
     */
    @Override
    public CommonResult queryPartGraphInfo(Integer id) throws BusinessException {
        //查询该零件的所有子零件
        List<ProductInfoDO> result=new ArrayList<>();
        ProductInfoDO parent= productInfoDOMapper.selectByPrimaryKey(id);
        if(parent==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品信息失败！");
        }
        if(parent.getProductId()>=9999){
            List<ProductInfoDO> mid= productInfoDOMapper.selectByProductId(9999+parent.getId());
            if(mid==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品信息失败！");
            }
            //查询父零件的子零件
            for(ProductInfoDO i:mid){
                if(judgeSonStr(i.getOrderInfo(),parent.getOrderInfo())) result.add(i);
            }
        }else if(parent.getProductId()==0){
            result.add(parent);
        }else{
            List<ProductInfoDO> mid=productInfoDOMapper.selectByIdAndProductId(parent.getUserId(),parent.getProductId());
            if(mid==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品信息失败！");
            }
            //查询父零件的子零件
            for(ProductInfoDO j:mid){
                if(judgeSonStr(j.getOrderInfo(),parent.getOrderInfo())) result.add(j);
            }
        }

        //转变为图结点和关系
        List<GraphNodeVO> list=new ArrayList<>();
        GraphNodeVO pare=new GraphNodeVO();
        pare.setNameInfo(parent.getNameInfo());
        pare.setId(parent.getId());
        pare.setLevel(0);
        //对零件进行分级
        for(ProductInfoDO productInfoDO:result){
            list.add(convertFromProductInfoDO(productInfoDO,parent.getNameInfo(),parent.getOrderInfo()));
        }


        List<GraphRelationNode> graphRelationNodeList=new ArrayList<>();
        for(GraphNodeVO i:list){
            graphRelationNodeList.add(convertFromNodeVO(i));
        }
        GraphVO r=new GraphVO(0,list,graphRelationNodeList);
        return CommonResult.create(r);
    }


    //查询零件的信息

    /**
     * 该方法暂时没有用到
     * @param id
     * @return
     */
    @Override
    public List<ProductInfoDO> queryPartListInfo(Integer id) throws BusinessException {
        List<ProductInfoDO> result=new ArrayList<>();

        ProductInfoDO parent= productInfoDOMapper.selectByPrimaryKey(id);
        if(parent==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品信息失败！");
        }
        if(parent.getProductId()>=9999){
            List<ProductInfoDO> mid= productInfoDOMapper.selectByProductId(9999+parent.getId());
            if(mid==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品信息失败！");
            }

            //查询父零件的子零件
            for(ProductInfoDO i:mid){
                if(judgeSonStr(i.getOrderInfo(),parent.getOrderInfo())) result.add(i);
            }
        }else if(parent.getProductId()==0){
            result.add(parent);
        }else{
            List<ProductInfoDO> mid=productInfoDOMapper.selectByIdAndProductId(parent.getUserId(),parent.getProductId());
            if(mid==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取产品信息失败！");
            }
            //查询父零件的子零件
            for(ProductInfoDO j:mid){
                if(judgeSonStr(j.getOrderInfo(),parent.getOrderInfo())) result.add(j);
            }
        }
        return result;
    }


    //提交零件的bom表

    /**
     * 该方法暂时没有用到
     * @param productInfoDO
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void submitBom(List<ProductInfoDO> productInfoDO) throws BusinessException {
        if(productInfoDO==null||productInfoDO.size()==0) return;
        ProductInfoDO first=productInfoDO.get(0);
        int i1 = productInfoDOMapper.insertSelective(first);
        if(i1==0){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"插入失败！");
        }
        for(int i=1;i<productInfoDO.size();i++){
            productInfoDO.get(i).setProductId(9999+first.getId());
            int i2 = productInfoDOMapper.insertSelective(productInfoDO.get(i));
            if(i2==0){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"插入失败！");
            }
        }
    }

    //提交单个零件
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public int submitPart(ProductInfoDO productInfoDO) {
        return productInfoDOMapper.insertSelective(productInfoDO);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void deleteById(Integer id) throws BusinessException {
        int i = productInfoDOMapper.deleteByProductId(id);
        if(i==0){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"删除零件信息失败！");
        }
    }


    private ProductModel convertFromProductDO(ProductDO productDO){
        if(productDO==null){
            return null;
        }
        ProductModel productModel=new ProductModel();
        BeanUtils.copyProperties(productDO,productModel);
        return productModel;
    }


    private ProductModel convertFromProductInfoDO(List<ProductInfoDO> productInfoDOList){
        if(productInfoDOList==null){
            return null;
        }
        ProductModel productModel=new ProductModel();
        BeanUtils.copyProperties(productInfoDOList,productModel);
        return productModel;
    }


    private ProductModel convertFromDOAndInfoDO(ProductDO productDO,List<ProductInfoDO> productInfoDOList){
        if(productInfoDOList==null||productDO==null){
            return null;
        }
        ProductModel productModel=new ProductModel();
        BeanUtils.copyProperties(productDO,productModel);
        productModel.setProductInfoDOList(productInfoDOList);
        return productModel;
    }

    private GraphNodeVO convertFromProductInfoDO(ProductInfoDO productInfoDO, String parentName,String parentorderinfo){
        GraphNodeVO graphNodeVO=new GraphNodeVO();
        BeanUtils.copyProperties(productInfoDO,graphNodeVO);
        String order=productInfoDO.getOrderInfo();
        String[] plevel=parentorderinfo.split("\\.");
        int l=plevel.length;

        String[] orders=order.split("\\.");
        //设置等级
        graphNodeVO.setLevel(orders.length);
        //设置父节点
        if(orders.length==l+1){
            //他们的父零件就是产品本身
            graphNodeVO.setParentorder(parentName);
        }else{
            //他们的父节点就是小数点前一串字母
            int lastdotindex=0;
            for(int i=order.length()-1;i>=0;i--){
                if(order.charAt(i)=='.'){
                    lastdotindex=i;
                    break;
                }
            }
            graphNodeVO.setParentorder(order.substring(0,lastdotindex));
        }
        return graphNodeVO;
    }

    private GraphRelationNode convertFromNodeVO(GraphNodeVO graphNodeVO){
        if(graphNodeVO.getLevel()==null){
            return null;
        }
        GraphRelationNode graphRelationNode=new GraphRelationNode();
        graphRelationNode.setParent(graphNodeVO.getParentorder());
        graphRelationNode.setChild(graphNodeVO.getOrderInfo());
        graphRelationNode.setName(graphNodeVO.getLevel()+"级零件");
        graphRelationNode.setDes("无");
        return graphRelationNode;
    }


    private boolean judgeSonStr(String parent,String son){
        if(parent.length()<=son.length()) return false;
        int n=son.length();
        return parent.substring(0,n).equals(son);
    }


}
